package fiuba.algo3.algothief;

import java.util.ArrayList;

import org.w3c.dom.Document;
import org.w3c.dom.Element;


public abstract class Jugador {

	protected String nombre;
	protected String rango;
	protected Ciudad ciudadActual;
	protected float tiempoRestante;
	protected int cantLugaresVisitadosEnCiudad;
	protected int velocidad;
	protected Interpol interpol;
	protected boolean ordenDeArresto;
	protected boolean EncontreAlLadron;
	protected AlarmasPistas alarmaGanarJuego;
	protected AlarmasPistas alarmaMeAcuchillaron;
	protected AlarmasPistas alarmaRecibiBalazo;

	public Jugador(String nombre, Ciudad ciudadActual, float tiempo,Interpol interpol) {
		this.nombre = nombre;
		this.ciudadActual = ciudadActual;
		this.tiempoRestante = tiempo;
		this.ordenDeArresto = false;
		this.cantLugaresVisitadosEnCiudad = 0;
		this.interpol = interpol;
		this.EncontreAlLadron = false;
		this.alarmaGanarJuego = null;
		this.alarmaMeAcuchillaron = null;
		this.alarmaRecibiBalazo = null;
	}
	
	
	public void setAlarmaGanarJuego(AlarmasPistas alarma){
		this.alarmaGanarJuego = alarma;
	}
	
	
	public void setAlarmaMeAcuchillaron(AlarmasPistas alarma){
		this.alarmaMeAcuchillaron = alarma;
	}
	
	
	public void setAlarmaRecibiBalazo(AlarmasPistas alarma){
		this.alarmaRecibiBalazo = alarma;
	}
	

	public Ciudad getCiudadActual() {
		return this.ciudadActual;
	}
	

	public float getTiempoRestante() {
		return this.tiempoRestante;
	}
	

	public boolean getEncontreAlLadron() {
		return this.EncontreAlLadron;
	}
	

	protected float calcularTiempo(Ciudad ciudadFinal, float velocidad) {
		float distancia;
		distancia = this.ciudadActual.distanciaA(ciudadFinal);
		float tiempoCalculado = distancia / velocidad;
		return tiempoCalculado;
	}
	

	protected void viajar(Ciudad ciudadDestino) throws TeQuedasteSinTiempo {
		float velocidad = this.velocidad;
		float tiempo = this.calcularTiempo(ciudadDestino, velocidad);
		if (tiempoRestante < tiempo) {
			throw new TeQuedasteSinTiempo();
		} else {
			this.restarTiempo(tiempo);
			this.ciudadActual = ciudadDestino;
			this.cantLugaresVisitadosEnCiudad = 0;
		}
	}
	
	protected void restarTiempo(float tiempo) {
			this.tiempoRestante = this.tiempoRestante - tiempo;
		}
	

	public ArrayList<String> emitirOrdenDeArresto(String sexo, String hobby, String cabello, String senia, String vehiculo) {
			ArrayList<String> listaCriminales = interpol.filtrarCriminales(sexo, hobby, cabello, senia, vehiculo);
			this.ordenDeArresto = interpol.verificarSiEsElCriminalCorrecto(listaCriminales);
			this.tiempoRestante = this.tiempoRestante - 3;
			return listaCriminales;
	}
	

	public abstract Pista pedirPistaEnLugar(int posicion)throws TeQuedasteSinTiempo;

	
	public Element serializar(Document doc) {
		Element elementoJugador = doc.createElement("Jugador");
		elementoJugador.setAttribute("nombre", this.nombre);
		elementoJugador.setAttribute("tiempoRestante",Float.toString(this.tiempoRestante));
		elementoJugador.setAttribute("cantLugaresVisitadosEnCiudad",Integer.toString(this.cantLugaresVisitadosEnCiudad));
		elementoJugador.setAttribute("velocidad",Integer.toString(this.velocidad));
		elementoJugador.setAttribute("ordenDeArresto",Boolean.toString(this.ordenDeArresto));
		elementoJugador.setAttribute("encontreAlLadron",Boolean.toString(this.EncontreAlLadron));
		elementoJugador.appendChild(this.interpol.serializar(doc));
		elementoJugador.appendChild(this.ciudadActual.serializar(doc));
		return elementoJugador;
	}

	
	public void recibirCuchillazo() throws TeQuedasteSinTiempo {
		if (this.tiempoRestante < 4) {
			throw new TeQuedasteSinTiempo();
		} else {
			setearTiempo(getTiempoRestante()-4);
			alarmaMeAcuchillaron.enviarAlarma(this);
		}
	}
	

	public void recibirBalazo() throws TeQuedasteSinTiempo {
		if (this.tiempoRestante < 8) {
			throw new TeQuedasteSinTiempo();
		} else {
			setearTiempo(getTiempoRestante()-8);
			alarmaRecibiBalazo.enviarAlarma(this);	
		}
	}

	
	public void ganar() {
		if (this.ordenDeArresto){
			Juego.incrementarCasosResueltos();
		}
		alarmaGanarJuego.enviarAlarma(this);
	}

	
	public void setearTiempo(float tiempo) {

		if (tiempo < this.tiempoRestante) {
			this.tiempoRestante = tiempo;
		}
	}
	

	public void setInterpol(Interpol interpol) {
		this.interpol = interpol;
	}
	

	public String getNombre() {
		return this.nombre;
	}
	
	
	public String getRango() {
		return this.rango;
	}
	
	
	public Interpol getInterpol() {
		return this.interpol;
	}
}
